#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>

using namespace std;

#define BEGINS(x) namespace x {
#define ENDS(x) } // end of namespace x

BEGINS(even_test)

//    template<int N>
//    struct YES_OR_NO {
//        static const char *r;
//    };
//
//    template<>
//    struct YES_OR_NO<0> {
//        static const char *r;
//    };

//    template<int N>
//    const char *YES_OR_NO<N>::r = "yes";
//    const char *YES_OR_NO<0>::r = "no";

    template<int N>
    struct is_even {
        static constexpr const char *r = (N % 2 ? "no" : "yes");
    };
//    template<int N>
//    const char *is_even<N>::r = YES_OR_NO<!(N % 2)>::r;

    int main() {
        cout << is_even<5>::r << endl;    // no
        cout << is_even<6>::r << endl;    // yes
        return 0;
    }

ENDS(even_test)

BEGINS(sum_test)

    template<int N>
    struct sum {
        static constexpr int r = N + sum<N - 1>::r;

    };

    template<>
    struct sum<1> {
        static constexpr int r = 1;
    };

    int main() {
        cout << sum<5>::r << endl;    // sum of 10 5
        cout << sum<7>::r << endl;    // sum of 1 - 7
        cout << sum<100>::r << endl;  // sum of 1 - 100
        return 0;
    }

ENDS(sum_test)

BEGINS(good_bad_test)

    template<int N> struct ZERO;
    template<>
    struct ZERO<0> {
        static constexpr char *r = "bad";
    };
    template<>
    struct ZERO<1> {
        static constexpr char *r = "good";
    };

    template<int N>
    struct score_judge {
        static constexpr char *r = ZERO<N >= 60>::r;
    };

    int main() {
        cout << score_judge<60>::r << endl;    // good
        cout << score_judge<54>::r << endl;    // bad
        return 0;
    }

ENDS(good_bad_test)

BEGINS(is_prime_test)
    template<int i, int N>
    struct getNext {
        static constexpr int r = (N % i ? i + 1 : 0);
    };

    template<int i, int N>
    struct test {
        static constexpr const char *r
        = ((i * i > N) ? "yes" : test< getNext<i, N>::r, N>::r);
    };

    template<int N>
    struct test<0, N> {
        static constexpr const char *r = "no";
    };

    template<int N>
    struct is_prime {
        static constexpr const char *r = test<2, N>::r;
    };

    int main() {
        cout << is_prime<2>::r << endl;    // yes
        cout << is_prime<3>::r << endl;    // yes
        cout << is_prime<5>::r << endl;    // yes
        cout << is_prime<8>::r << endl;    // no
        cout << is_prime<103>::r << endl;    // yes
        return 0;
    }

ENDS(is_prime_test)

int main() {
    even_test::main();
    sum_test::main();
    good_bad_test::main();
    is_prime_test::main();
    return 0;
}